using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using DG.Tweening;

//控制场上单个球渲染的脚本
//目前渲染的方式是直接把prefab挂到自己下面
public class FieldBallView : MonoBehaviour, IPointerDownHandler
{
  public struct Model
  {
    public int relatedPtr;
    public Vector2Int position;
    public BallInfo info;
    public Vector2Int gridSize;
    public bool isAlive;
  }

  public struct Handlers
  {
    public Action<int> removeFromUpperView;
    public Func<int, BallResources> loadResources;
    public Func<Vector2Int, Vector2> gridPositionToWorld;
  }

  private struct State
  {
    public bool isRendering;
    public bool interactable;

    public void ResetState() {
      isRendering = false;
      interactable = false;
    }

    public void OnStartRender() {
      isRendering = true;
      interactable = true;
    }
  }

  private SpriteRenderer m_spriteRenderer;

  private Model m_cachedViewModel;

  private State m_state;

  public Model viewModel => m_cachedViewModel;
  public int relatedPtr => m_cachedViewModel.relatedPtr;

  public Handlers handlers {
    private get; set;
  }

  public void Render(Model viewModel) {

    if (viewModel.relatedPtr != 0)
    {
      if (m_state.isRendering && viewModel.relatedPtr != m_cachedViewModel.relatedPtr)
      {
        Clear();
      }
      if (m_state.isRendering && viewModel.relatedPtr == m_cachedViewModel.relatedPtr)
      {
        UpdateView(viewModel);
      }
      if (!m_state.isRendering)
      {
        StartView(viewModel);
      }
      m_cachedViewModel = viewModel;
    }
    if (m_state.isRendering && !viewModel.isAlive)
    {
      FadeOut();
    }
  }

  public void ForceSetPosition(Vector2 position) {
    transform.position = position;
  }

  public void OnPointerDown(PointerEventData eventData) {
    if (!m_state.interactable)
    {
      return;
    }
    PlayerSwapInput.Instance.OnPointerDown(viewModel.position, transform.position);
  }

  private void FadeOut() {
    if (m_spriteRenderer != null)
    {
      m_state.interactable = false;
      m_spriteRenderer.SetAlpha(1);
      m_spriteRenderer.DOFade(0, FieldView.RENDER_STEP).OnComplete(() => Clear());
    }
  }

  private void StartView(Model viewModel) {
    var id = viewModel.info.id;
    var resources = handlers.loadResources(id);
    if (resources == null) return;
    var prefab = resources.prefab;
    var instObj = Instantiate(prefab, transform);
    m_spriteRenderer = instObj.GetComponent<SpriteRenderer>();
    m_state.OnStartRender();
    UpdateView(viewModel);
  }

  private void UpdateView(Model viewModel, bool isInit = false) {
    transform.DOMove(handlers.gridPositionToWorld(viewModel.position), FieldView.RENDER_STEP);
  }

  private void Clear() {
    handlers.removeFromUpperView?.Invoke(m_cachedViewModel.relatedPtr);
    transform.DestroyAllChildren();
    m_state.ResetState();

    Destroy(gameObject); // 暂时先彻底销毁
  }

}
